/*
 * Created on 2005/04/30
 * Author aki@www.xucker.jpn.org
 * License Apache2.0 or Common Public License
 */
package jp.sourceforge.akjrcp.audiotools.spectrogram;

import org.eclipse.draw2d.AbstractHintLayout;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FlowLayout;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import jp.sourceforge.akjrcp.ui.draw2d.FileImageCache;
import jp.sourceforge.akjrcp.ui.draw2d.ScalableImageFigure;

import java.io.File;
import java.util.Iterator;

/**
 * 
 *
 */
public class SpectrogramListFigure extends Figure implements SpectrogramDrawInfo{
public static Log log = LogFactory.getLog(SpectrogramListFigure.class);
private int samplerate=48000;
public static final int MAX_SAMPLERATE=48000;
private int baseHeight=512;
private boolean fit;
private double vzoom=1;
private double wzoom=1;

private double offsetX;	//some case you have to set because spectrom ignore first height samples. 
private boolean drawUnder=true;
public SpectrogramListFigure(){
   // FlowLayout layout=new FlowLayout(true);
   // layout.setMajorSpacing(0);
    //layout.setMinorSpacing(0);
    setLayoutManager(new ListLayout());
    setSize(100,baseHeight);//this is dummy
}
//now just horizontal only
public class ListLayout extends AbstractHintLayout{

	protected Dimension calculatePreferredSize(IFigure arg0, int arg1, int arg2) {
		return arg0.getPreferredSize(arg1, arg2);
	}

	public void layout(IFigure parent) {
		
		Iterator iterator = parent.getChildren().iterator();
		double dx=(int) (offsetX*wzoom);
		
		//i know this is a problem of layout system.
		//but i dont know how to fix it ,now just let them go.
		if(getParent().getBounds().x<0){//something special treatment for location
			//log.warn("parentx is wrong."+getParent().getBounds().x);
			dx+=getParent().getBounds().x;//need it.
		}
		// log.info("layout:"+getClientArea());
		//  log.info("layout-parent:"+getParent().getClientArea());
		//  log.info("layout:-dx="+dx);
		int marginY=0;
		int dy=0;
		if(drawUnder){
			dy=getClientArea().height-baseHeight-marginY;//should care of baseHeight
			}
		while (iterator.hasNext()) {
			SpectrogramFigure f = (SpectrogramFigure)iterator.next();
			Dimension d=f.getPreferredSize();
			Rectangle rect=new Rectangle((int)dx,dy,d.width,d.height);
			//log.infofigure:"+rect); //all must be same
			f.setBounds(rect);
			dx+=f.calculateImageWidth();//now seems better
		}
	}
	
}

public int getBaseHeight() {
    return baseHeight;
}
public void setBaseHeight(int baseHeight) {
    this.baseHeight = baseHeight;
}
public boolean isFit() {
    return fit;
}
public void setFit(boolean fit) {
    this.fit = fit;
    //  TODO re fit all children?
}
public int getSampleRate() {
    return samplerate;

}
public void setSampleRate(int samplerate) {
    this.samplerate = samplerate;
    //  TODO re sample all children?
}

public double getVzoom() {
    return vzoom;
}
public void setVzoom(double vzoom) {
    this.vzoom = vzoom;
}
public double getWzoom() {
    return wzoom;
}
public void setWzoom(double wzoom) {
    this.wzoom = wzoom;
    IFigure[] figures=(IFigure[])getChildren().toArray(new IFigure[getChildren().size()]);
    for(int i=0;i<figures.length;i++){
        if(figures[i] instanceof ScalableImageFigure){
            ((ScalableImageFigure)figures[i]).setScale(wzoom,vzoom);
        }
    }
    revalidate();
}
public void setZoom(double w,double v){
    setVzoom(v);
    setWzoom(w);
   
    
    /*
    if(spectrogramImage!=null && !spectrogramImage.isDisposed()){
    setSize((int)(spectrogramImage.getBounds().width*wzoom),(int)(baseHeight*vzoom));
    }*/
    
    //TODO resize all children?
}

public void paintFigure(Graphics g){
	//setSize(2000,512);
   
    
   // g.setBackgroundColor(ColorConstants.red);
    //g.fillRectangle(0,0,100,100);
    //Rectangle clientArea = getClientArea();
    
   // log.info(this.getClientArea());
 //   log.info(this.getSize());
    /*
    if(spectrogramImage!=null && !spectrogramImage.isDisposed()){
         
        if(fit){
            g.drawImage(spectrogramImage,0,0,spectrogramImage.getBounds().width,spectrogramImage.getBounds().height,clientArea.x,clientArea.y,this.getSize().width,this.getSize().height);
                
        }else{
            int drawHeight=(int)(samplerate*baseHeight*vzoom/MAX_SAMPLERATE);
           // log.info(drawHeight);
            g.drawImage(spectrogramImage,0,0,spectrogramImage.getBounds().width,spectrogramImage.getBounds().height,clientArea.x,clientArea.y+clientArea.height-drawHeight,this.getSize().width,drawHeight);
        }
        }
    */
    }
/**
 * @param imageWidth
 * @param compositeHeight
 * @param i
 * remove all children figure & resize figure.
 */
public void init(int imageWidth, int compositeHeight, int totalPixelSize,FileImageCache imageCache,File baseFolder) {
    this.removeAll();
    baseHeight=compositeHeight;
    log.warn("pixelSize = "+totalPixelSize+",imageWidth="+imageWidth);
    int figureNumber=totalPixelSize/imageWidth;
   
    if(totalPixelSize%imageWidth>0){
        figureNumber++;//add mod
    }
    log.trace("image-Figure-Size:"+figureNumber);
    for(int i=0;i<figureNumber;i++){
        SpectrogramFigure scalableImageFigure=new SpectrogramFigure(this,imageCache,new File(baseFolder,toLabel(i)+".gif").getAbsolutePath(),imageWidth,compositeHeight);
        scalableImageFigure.setScale(wzoom,vzoom);
        add(scalableImageFigure);
    }
    
    this.revalidate();
}
//update figures
public static String toLabel(int v){
    int k=5;
    String ret=""+v;
    while(ret.length()<k){
        ret="0"+ret;
    }
    return ret;
}
public double getOffsetX() {
	return offsetX;
}
public void setOffsetX(double offsetX) {
	this.offsetX = offsetX;
}

}
